#ifndef DATE_TIME_H
#define DATE_TIME_H

#include <ctime>
#include <string>
#include <memory>

namespace base
{
namespace utils
{
/**
 * @brief:  时间处理工具库，精确到毫秒
 * @author: sherlock_lht
 */
class DateTime
{
public:
  /**
   * 返回当前的时间戳转换的秒数(从1970-01-01T00:00:00开始计算)
   */
  static long long currentSecond();

  /**
   * 返回当前时间戳
   */
  static DateTime currentDateTime();

  /**
   * tm转换成秒数(从1970-01-01T00:00:00开始计算)
   */
  static long long tm2Second(tm *tm);

  /**
   * 秒数(从1970-01-01T00:00:00开始计算)转换成tm
   */
  static std::tm *second2Tm(long long second);

public:
  DateTime();
  DateTime(const DateTime &dateTime);
  explicit DateTime(std::tm *tm);
  explicit DateTime(long long second);
  explicit DateTime(long long second, long long msecond);
  virtual ~DateTime();

  DateTime addDays(int days) const;

  DateTime addSecond(long long seconds) const;

  DateTime addMillSecond(long long msecond) const;

  /**
   * 格式化时间
   * These expressions may be used for the date:
   * d    :   the day as number without a leading zero (1 to 31)
   * dd   :   the day as number with a leading zero (01 to 31)
   * ddd  :   the abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses the system locale to localize the name, i.e. QLocale::system().
   * dddd :   the long localized day name (e.g. 'Monday' to 'Sunday'). Uses the system locale to localize the name, i.e. QLocale::system().
   * M    :   the month as number without a leading zero (1-12)
   * MM   :   the month as number with a leading zero (01-12)
   * MMM  :   the abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses the system locale to localize the name, i.e. QLocale::system().
   * MMMM :   the long localized month name (e.g. 'January' to 'December'). Uses the system locale to localize the name, i.e. QLocale::system().
   * yy   :   the year as two digit number (00-99)
   * yyyy :   the year as four digit number
   * h    :   the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
   * hh   :   the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
   * H    :   the hour without a leading zero (0 to 23, even with AM/PM display)
   * HH   :   the hour with a leading zero (00 to 23, even with AM/PM display)
   * m    :   the minute without a leading zero (0 to 59)
   * mm   :   the minute with a leading zero (00 to 59)
   * s    :   the second without a leading zero (0 to 59)
   * ss   :   the second with a leading zero (00 to 59)
   * z    :   the milliseconds without leading zeroes (0 to 999)
   * zzz  :   the milliseconds with leading zeroes (000 to 999)
   * AP/A :   use AM/PM display. A/AP will be replaced by either "AM" or "PM".
   * ap/a :   use am/pm display. a/ap will be replaced by either "am" or "pm".
   */
  std::string toString(const std::string &format) const;

  long long toSecond() const;

  long long toMilliSecond() const;

private:
  time_t sec;
  long long int msec;
};
}
}

#endif //DATE_TIME_H
